# SSN - game
# Copyright (c) 2009, jonoerik
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
# conditions are met:
#
#    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
#	disclaimer.
#    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
#	disclaimer in the documentation and/or other materials provided with the distribution.
#    * The names of contributors may not be used to endorse or promote products derived from this software without specific
#	prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

#game
#contains crucial game settings and variables

#library imports
from sys import path as syspath
syspath.append('.//libtcod-1.4.1')
import libtcodpy as libtcod
import numpy

#ssn imports
import map
import actors
import graphics
import input
from util import *

class ssn_game:
    '''core game settings, constants, and variables'''
    
    #constants
    #window settings
    const_window_width = 80
    const_window_height = 60
    #map size
    const_map_width = 300
    const_map_height = 300
    
    #bsp map generation params
    const_bsp_recursion_levels = 10
    const_bsp_min_w = 20
    const_bsp_min_h = 20
    const_bsp_max_wh_ratio = 2
    const_bsp_max_hw_ratio = 2
    #the amout of space to leave around each building
    #normal street size will be double this
    const_building_border = 2
    #inverse density of doors per wall tiles
    #if density value is 30, 1 in every 30 wall tiles will contain a door
    const_building_door_density = 70
    #number of building areas per courtyard
    const_areas_per_courtyard = 7
    #number of building areas per park / garden
    const_areas_per_park = 12
    #inverse density of objects in parks
    #if density value is 4, 25% of tiles will be of that object
    const_park_tree_density = 10
    const_park_rock_density = 30
    #the number of common npcs on the map
    const_crowd_count = 100
    const_crowd_colors = (libtcod.dark_sky, libtcod.dark_blue, libtcod.dark_violet, libtcod.dark_magenta, libtcod.dark_pink)
    #number of guards in buildings
    const_guard_count = 5
    
    #for building interiors
    #border to be left either side of new wall splits
    const_room_border = 5
    #number of split recursions to do on building interiors
    const_room_recursion_limit = 6
    #if a room's h/w or h/w ratio is larger, it wont be split in a way that makes it more elogated
    #this doesn't prevent long thin rooms, but it does help to lessen the number of them
    const_room_ratio_limit = 2.0
    #number of random doors to be added (these doors aren't needed for connectivity, but help with getting around)
    const_room_extra_doors = 8
    
    #the default pc/npc speeds
    const_speed_pc = 80
    const_speed_npc = 100
    const_speed_sprint_multiplier = 5
    
    
    #customisable key bindings
    #action:(key, character)
    #eg 'rest':(libtcod.KEY_CHAR, 'R')
    #currently, movement keys must be non KEY_CHAR keys
    key_bindings = {
        'up':(libtcod.KEY_UP,None),
        'down':(libtcod.KEY_DOWN,None),
        'left':(libtcod.KEY_LEFT,None),
        'right':(libtcod.KEY_RIGHT,None),
        'sprint':(libtcod.KEY_SHIFT,None),
        'quit':(libtcod.KEY_ESCAPE,None),
        'toggle fps':(libtcod.KEY_F12,None),
        'regenerate map':(libtcod.KEY_F11,None),
        'take screenshot':(libtcod.KEY_F10,None)
    }
    
    def __init__(self):
        print 'Setup Started'
        self.running = True
        self.window_width = self.const_window_width
        self.window_height = self.const_window_height
        
        #the location of the upper left corner of the window on the map
        self.scroll_x = 0
        self.scroll_y = 0
        
        self.show_fps = False
        
        self.load_area('city')
        
        print 'Initializing Graphics...',
        libtcod.console_disable_keyboard_repeat()
        libtcod.console_init_root(self.const_window_width, self.const_window_height, "SSN", False)
        print 'Done'
        print 'Setup Done \n'
    
    def load_area(self, area):
        self.carea = area
        if area == 'city':
            print 'Creating Map...',
            self.map = map.ssn_map(self, self.const_map_width, self.const_map_height)
            self.map.gen_city(self)
            print 'Done'
            print 'Adding Characters...',
            self.actors = actors.actor_handler()        
            self.actors.add_pc(self, None)
            self.actors.add_crowds(self, self.const_crowd_count)
            print 'Done'
        elif area == 'building':
            print 'Creating Map...',
            self.map = map.ssn_map(self, self.const_window_width, self.const_window_height)
            self.map.gen_building(self)
            print 'Done'
            print 'Adding Characters...',
            self.actors = actors.actor_handler()        
            self.actors.add_pc(self, None)
            for i in xrange(self.const_guard_count):
                self.actors.add_guard(self, None)
            print 'Done'